LN technical details
Details of how LN chennel is implemented. Such as architecture of commitment transaction.
LN のメッセージの形式
type は奇数
取引の流れ
チャネルをつくって state を update する。これはかんたん
どうやって前の state を無効にするか
すべての to_self output はタイムロック OR remote が revocation key ですぐに unlock できる。
relay するにはどうするか
HTLC を連鎖させる
HTLC なしで commitment tx の更新を考える
commitment tx は 2of2 multisig の funding tx を unlock するため双方の署名が必要
相手側の commitment tx をつくって署名して、署名だけわたすのかな?
commitment tx は非対称なのことに注意
署名を渡すコマンドが commitment_signed
前の commitment tx の再利用を防ぐために、revocation key を生成できるシークレットを渡す
これが revoke_and_ack
Invoice を発行
送金
Alice --> Bob --> Carol と送金する
Channel の状態を変化させるためには update_add_htlc がまず用いられる
update_add_htlc は、相手の commitment tx に HTLC の追加を依頼するコマンドと言える
Alice が Bob に投げる
update_add_htlc により新しい commitment tx が定義されるが、まだ署名は渡っていない。署名は 前述の commitment_signedで渡される
つまり、update_add_htlc と commitment_signed はセット。update_add_htlc は複数でも良いが、対応する 署名が必要。
Alice が Bob になげる
Bob は Carol に update_add_htlc を投げる前に、alice の前の commitment tx を revoke しないといけない
Alice はすでに新しい commitment tx は知っているので、Bob から Alice に commitment_signed で署名を渡す
Alice から Bob に revoc_and_akc
ここまでいけば、Bob は Carol に対して同じことをする
Commitment transaction
funding tx を unlock する
channel open 時には funding tx と最初の commitment tx(refund tx とも呼ぶ) が作られる
6種類の lock の方法がある
to_local(P2WPKH)
unlock 条件
to_self_delay
revoc key, remote_sig
to_remote(P2WPKH)
remote sig
anchor tx 2種類
HTLC は多段
The reason for the separate transaction stage for HTLC outputs is so that HTLCs can timeout or be fulfilled even though they are within the to_self_delay delay. Otherwise, the required minimum timeout on HTLCs is lengthened by this delay, causing longer timeouts for HTLCs traversing the network.
あまりよくわかっていない、、、
local への支払いは常に to_self 分の delay が必要で、timeout した HTLC を取り戻す場合にも to_self delay が必要。
そうでなければ、HTLC output は CLTV 後はいつでも使える状態になり、仮に HTLC が fullfied であったとしても、すぐに取り返すことができてしまう
なので、to_local の HTLC は CLTV による HTLC の expire 時間の設定に加えて、to_self delay が必要
つまり、HTLC は CLTV により expire しているのにも関わらず、それを自分に取り戻す場合はそれ以上に時間がかかることを意味する。つまり実質的な CLTV は CLTV + CSV。
もし CTLV delta がこの実質的な CLTV よりも小さい場合(delta < CLTV)、資金を失う可能性があるので、CLTV delta を 実質の CLTV よりも大きくする必要がある。
delta > CSV でないといけない?
なぜ資金を失う可能性があるか
Received HTLC は Offerd HTLC よりも早く expire してはいけない
Received HTLC の CLTV > Offerd HTLC の CLTV でないといけない
Received が先に expire すると、その資金は相手に戻る。でも自分の Offerd はまだ expire していないので、送金相手に送金される。自分は送ったのに、その分は受け取れない状況になっている
実質的な CLTV が CLTV + CSV である場合、CLTV delta は当然 CSV も含めて考える必要がある
delta が 5 block、Received CLTV が 105 block とすると、Offerd CLTV は 100 block。CSV は 10 block とする。
この時、Offerd の HTLC を回収するには minimum block 110 まで待つ必要がある(expire が block 100 で、プラス CSV 10 block 分)
received は 105 + 10 block で 115 block
問題なくない?
問題があるとすれば、receive を取り返せる前に、offerd が timeout するのでそちらの取り返し作業も始まってしまってレースになる?
しかしこの場合、次の Hop もこの timeout 時間の影響を受けることになる???
commitment tx の to_local には to_self_delay 分の timelock をかける。to_self_delay は割と長いので HTLCの timeout はこれよりも短い時間に設定できないと、ルーティングで資金がロックされる時間が長くなってしまう?
多段にする理由
There is still a problem: Making the output to Alice encumbered by both these timelocks could in the worst case extend the HTLC’s timeout by to_self_delay. In other words, Bob could have an extra to_self_delay blocks in order to sweep the hash-locked output even though the HTLC is technically expired.
From here, one can imagine a scenario where we have an HTLC that can be timed out (absolute block height passed), but we can't spend it (timing it out) until our CSV period has also expired. Therefore, one needs to set their CSV values taking into account the absolute timelock (CLTV) value as well. Critically, before a user can cancel their incoming off-chain HTLC (timing out the outgoing on-chain), they need to wait for this CSV period. However, if the CSV is greater than the time lock delta (diff between incoming and outgoing HTLCs), they've created a race and could possibly lose money.
一段の問題点
CLTV で expire していても、CSV を待っている間に preimage を使って送金を完了させることができてしまう
もちろん完了されてしまったら、自分も preimage を使って受け取ればよいのだが、そのためには自分の CSV を待つ間は、offerd HTLC の CLTV はまだ expire していない必要がある。となると CLTV の値は非常に大きくなってしまう。これが上で説明されていること。
2段にすると
CLTV expire した時点で、HTLC output は HTLC timeout tx で消費できるので、preimage を使って送金を完了することはできない。ゆっくり CSV を待てば良い。
Offered(outgoing) HTLC output
自分から送金する HTLC
unlock 条件
revoc key, remote sig
preimage, remote sig
HTLC-timeout tx
HTLC の expire 時間を指定するので絶対時間での timelock が必要
Received(incoming) HTLC output
受け取る HTLC
unlock 条件
revoc key, remote sig
HTLC-success tx
HTLC-timeout tx
CLTV で timelock
HTLC-Timeout and HTLC-Success Transactions
These HTLC transactions are almost identical, except the HTLC-timeout transaction is timelocked.
HTLC-timeout tx は input になる HTLC tx の script で CLTV による timelock がかけられる
Offerd HTLC tx か Received HTLC tx を input にする
署名
success tx: マルチシグ, preimage
timeout tx: マルチシグ
unlock 条件
revoc key, remote sig
CSV timelock, local sig
timeout する場合の説明
to self delay CSV はチャネルごとに決まっている
送金はどのように行われるか
HTLC を追加
update_add_htlc は複数可能
流れ
update_add_htlc で送金リクエスト。
update_add_htlc の受けては、ローカルの commitment tx をその内容に従って作成し、署名する。commitment_signed で署名を送る?
update_add_htlc の送り手は、commitment_signed が正しければ、ローカルの commitment tx を更新する?そして revoke_and_ack を返す?
リレーを atomic に行うため
A - B - C と送金する場合(A が B を経由して C に送金したい)
B は C に渡したけど、A から受け取れない可能性がある
A は B に渡したけど、B が C に渡さない可能性がある
A は C しか知らない値(preimage)で、 B への送金をロックする(hash(preimage)が unlock には必要) + 取り戻す用の timelock
これが HTLC
B は自分は送ったのに、先に A に取り戻されると困る
そのため、B-C の HTLC の timelock は A-C の HTLC の timelock よりも短くないといけない
A-B timelock < B-C timelock だと、C が preimage を明かしたタイミング(つまり B-C の timelock よりも前)で、すでに A が取り戻せる可能性がある(こちらの方が timelock が開けるのが早いので)
C が preimage を明かしたあとに、B がそれを使って A-B の HTLC から資金を受け取れるのに十分な時間差が必要
まて
The reason for the separate transaction stage for HTLC outputs is so that HTLCs can timeout or be fulfilled even though they are within the to_self_delay delay. Otherwise, the required minimum timeout on HTLCs is lengthened by this delay, causing longer timeouts for HTLCs traversing the network.
Channel close